using System;
using System.Collections;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace ZombieHigh2.DeleD
{
    public class Material
    {
        public int id;
        public String texturename;
    }

    public class Primitive3D
    {
        public String userInfo;
        public String name;
        public ArrayList polygons = new ArrayList();
        BoundingBox bbox;

        public BoundingBox BBox
        {
            get { return bbox; }
        }

        public Primitive3D()
        {
            polygons = new ArrayList();
        }

        public void AddPolygon(Polygon polygon)
        {
            polygons.Add(polygon);
        }

        public void CalculateBoundingBox()
        {
            Vector3 min = ((Vertex)((Polygon)polygons[0]).vertices[0]).GetVector3();
            Vector3 max = ((Vertex)((Polygon)polygons[0]).vertices[0]).GetVector3();

            foreach (Polygon poly in polygons)
            {
                foreach (Vertex vertex in poly.vertices)
                {
                    min = Vector3.Min(vertex.GetVector3(), min);
                    max = Vector3.Max(vertex.GetVector3(), max);
                }
            }

            bbox = new BoundingBox(min, max);
        }

        public static Vector3 CalculateCenter(Primitive3D primitive)
        {
            return new Vector3(primitive.bbox.Max.X + primitive.bbox.Min.X,
                primitive.bbox.Max.Y + primitive.bbox.Min.Y,
                primitive.bbox.Max.Z + primitive.bbox.Min.Z) / 2.0f;
        }
    }

    public class Vertex
    {
        public float x;
        public float y;
        public float z;

        public Vector3 GetVector3()
        {
            return new Vector3(x, y, z);
        }
    }

    public class Polygon
    {
        public ArrayList vertices;
        public int materialID;
        BoundingBox boundingBox;

        public BoundingBox BBox
        {
            get { return boundingBox; }
        }

        public Polygon()
        {
            vertices = new ArrayList();
            materialID = 0;
        }

        public void CalculateBoundingBox()
        {
            Vector3 min, max;
            min = (Vector3)((Vertex)vertices[0]).GetVector3();
            max = (Vector3)((Vertex)vertices[0]).GetVector3();
            //find min and max vectors
            foreach (Vertex vertex in vertices)
            {
                min = Vector3.Min(vertex.GetVector3(), min);
                max = Vector3.Max(vertex.GetVector3(), max);
            }

            boundingBox = new BoundingBox(min, max);
        }
    }

    public class TexturedPolygon : Polygon
    {

        public ArrayList textureCoords;
        Vector3 normal;

        public TexturedPolygon()
            : base()
        {
            textureCoords = new ArrayList();
        }

        public void AddTexturedVertex(Vertex vertex, float u0, float v0)
        {
            vertices.Add(vertex);
            textureCoords.Add(new TexturedVertex(u0, v0));
        }

        public void AddTexturedVertex(Vector3 vert, float u, float v)
        {
            Vertex vertex = new Vertex();
            vertex.x = vert.X;
            vertex.y = vert.Y;
            vertex.z = vert.Z;

            AddTexturedVertex(vertex, u, v);
        }

        void CalculateNormal()
        {
            Vector3 v1 = ((Vertex)vertices[0]).GetVector3() - ((Vertex)vertices[1]).GetVector3();
            Vector3 v2 = ((Vertex)vertices[2]).GetVector3() - ((Vertex)vertices[1]).GetVector3();

            v1.Normalize();
            v2.Normalize();

            normal = Vector3.Cross(v1, v2);
        }

        public VertexPositionNormalTexture[] GetVertices()
        {
            CalculateNormal();

            VertexPositionNormalTexture[] xnaVerts = new VertexPositionNormalTexture[vertices.Count];
            for (int i = 0; i < vertices.Count; i++)
            {
                xnaVerts[i] = new VertexPositionNormalTexture(((Vertex)vertices[i]).GetVector3(), normal, ((TexturedVertex)textureCoords[i]).Vector2);
            }

            return xnaVerts;
        }

    }

    public class TexturedVertex
    {
        public float u0;
        public float v0;

        public TexturedVertex(float u, float v)
        {
            this.u0 = u;
            this.v0 = v;
        }

        public Vector2 Vector2
        {
            get { return new Vector2(u0, v0); }
        }
    }
}
